package uno.rocc.framework.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import uno.rocc.framework.core.annotation.RoccUnoAuthorize;

import java.lang.reflect.Method;
import java.nio.file.AccessDeniedException;

@Slf4j
@Aspect
@Component
public class RoccUnoAuthorizeAspect {

    @Around("@annotation(roccUnoAuthorize)")
    public Object checkPermission(ProceedingJoinPoint joinPoint, RoccUnoAuthorize roccUnoAuthorize) throws Throwable {
        // 获取类上的注解value
        Class<?> targetClass = joinPoint.getTarget().getClass();
        RoccUnoAuthorize annotation = targetClass.getAnnotation(RoccUnoAuthorize.class);
        String prefix = "";
        if (annotation != null) {
            prefix = annotation.value();
        }

        // 得到全权限名
        String permission = prefix + roccUnoAuthorize.value();

        if (!checkPermission(permission)) {
            // 没有权限访问
            throw new AccessDeniedException("request forbidden!");
        }

        // 执行
        return joinPoint.proceed();
    }

    /**
     * 检查权限
     *
     * @param permission
     * @return
     */
    private boolean checkPermission(String permission) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        return auth.getAuthorities().stream().anyMatch(granted -> granted.getAuthority().equals(permission));
    }
}